package com.caiyigo.baihua.serviceImpl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.caiyigo.baihua.Const.Const;
import com.caiyigo.baihua.dao.SystemResMapper;
import com.caiyigo.baihua.dao.SystemRoleMapper;
import com.caiyigo.baihua.dao.SystemRoleResMapper;
import com.caiyigo.baihua.dto.Result;
import com.caiyigo.baihua.dto.RoleDto;
import com.caiyigo.baihua.dto.Tree;
import com.caiyigo.baihua.model.SystemRes;
import com.caiyigo.baihua.model.SystemRole;
import com.caiyigo.baihua.model.SystemUser;
import com.caiyigo.baihua.service.ResService;
import com.caiyigo.baihua.service.RoleService;
import com.caiyigo.baihua.shiro.ShiroCache;
import com.caiyigo.baihua.shiro.ShiroExt;
import com.caiyigo.baihua.utils.ListUtil;

/**
 * @author caihaihui
 * 
 */
@Transactional
@Service
public class RoleServiceImpl implements RoleService {
	@Autowired
	ResService resService;
	@Autowired
	SystemRoleMapper roleMapper;
	@Autowired
	SystemRoleResMapper roleResMapper;
	@Autowired
	SystemResMapper resMapper;

	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public boolean grant(int roleId, String resIds) {
		boolean result = false;
		/*
		 * if (!Validate.isEmpty(resIds)) result = Res.dao.batchAdd(roleId,
		 * resIds);
		 */
		if (resService.batchAdd(roleId, resIds) >= 0) {
			result = true;
		}
		ShiroCache.clearAuthorizationInfoAll();
		return result;
	}

	/***
	 * 批量授权 会先删除所有权限再授权
	 * 
	 * @param roleId
	 * @param resIds
	 * @return
	 */
	public Result batchGrant(int roleId, String resIds) {
		int result = roleResMapper.deleteByRoleId(roleId);
		if (result >= 0 && StringUtils.isNotEmpty(resIds)) {
			resService.batchAdd(roleId, resIds);
		}
		// if (!Validate.isEmpty(resIds)) result = Res.dao.batchAdd(roleId,
		// resIds);

		ShiroCache.clearAuthorizationInfoAll();
		
			return new Result(result >= 0);
		
	}

	public List<RoleDto> list() {
		List<RoleDto> list = roleMapper.list();

		for (RoleDto r : list) {
			List<SystemRes> res = resMapper.getRes(r.getId());
			r.setRes_ids(ListUtil.listToString(res, "id"));
			r.setRes_names(ListUtil.listToString(res, "name"));
		}
		return list;
	}

	public List<Tree> getTree(Integer id, Integer passId) {
		// 根据用户角色来获取 列表
		List<Tree> trees = new ArrayList<Tree>();

		for (SystemRole res : getChild(id)) {
			if (res.getId().equals(passId))
				continue;
			Tree tree = new Tree(res.getId(), res.getPid(), res.getName(),
					res.getIconCls(), res, false);

			tree.children = getTree(res.getId(), passId);
			if (tree.children.size() > 0)
				tree.changeState();

			trees.add(tree);
		}
		return trees;
	}

	public List<SystemRole> getChild(Integer id) {
		if (id == null)
			return roleMapper.selectWherePidIsNull();
		return roleMapper.selectByPid(id);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.RoleService#deleteByPrimaryKey(java.lang.Integer)
	 */
	@Override
	public int deleteByPrimaryKey(Integer id) {

		return roleMapper.deleteByPrimaryKey(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.RoleService#insert(com.caiyigo.zoo.model.SystemRole
	 * )
	 */
	@Override
	public int insert(SystemRole record) {

		return roleMapper.insert(record);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.RoleService#insertSelective(com.caiyigo.zoo.model
	 * .SystemRole)
	 */
	@Override
	public int insertSelective(SystemRole record) {

		return roleMapper.insertSelective(record);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.RoleService#selectByPrimaryKey(java.lang.Integer)
	 */
	@Override
	public SystemRole selectByPrimaryKey(Integer id) {

		return roleMapper.selectByPrimaryKey(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.RoleService#updateByPrimaryKeySelective(com.caiyigo
	 * .zoo.model.SystemRole)
	 */
	@Override
	public int updateByPrimaryKeySelective(SystemRole record) {

		return roleMapper.updateByPrimaryKeySelective(record);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.RoleService#updateByPrimaryKey(com.caiyigo.zoo
	 * .model.SystemRole)
	 */
	@Override
	public int updateByPrimaryKey(SystemRole record) {

		return roleMapper.updateByPrimaryKey(record);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.RoleService#getRolesName(java.lang.String)
	 */
	@Override
	public List<String> getRolesName(String name) {

		return roleMapper.getRolesName(name);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.RoleService#getRole(int)
	 */
	@Override
	public List<SystemRole> getRole(int id) {

		return roleMapper.getRole(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.RoleService#selectWherePidIsNull()
	 */
	@Override
	public List<SystemRole> selectWherePidIsNull() {

		return roleMapper.selectWherePidIsNull();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.RoleService#selectByPid(int)
	 */
	@Override
	public List<SystemRole> selectByPid(int id) {

		return roleMapper.selectByPid(id);
	}

	public boolean pidIsChild(Integer id, Integer pid) {
		boolean result = false;
		if (pid != null) {
			List<SystemRole> list = roleMapper.selectByPid(id);

			if (list.size() == 0)
				result = false;

			for (SystemRole r : list) {
				if (pid.equals(r.getId())) {
					result = true;
					return result;
				} else {

					if (pidIsChild(r.getId(), pid)) {
						result = true;
						return result;
					}
				}

			}
		}

		return result;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.caiyigo.zoo.service.RoleService#edit(com.caiyigo.zoo.model.SystemRole
	 * )
	 */
	@Override
	public Result edit(SystemRole role) {
		if (role.getId() == role.getPid())
			return new Result(false,"父节点不能为自己");
		else if (this.pidIsChild(role.getId(), role.getPid()))
			return new Result(false,"父节点不能为子节点");
		else if (roleMapper.updateByPrimaryKeySelective(role) > 0) {
			return new Result(true);
		}
		return new Result(false);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.RoleService#delete(java.lang.Integer)
	 */
	@Override
	public Result delete(Integer id) {
		for (SystemRole r : this.getRole(((SystemUser) ShiroExt
				.getSessionAttr(Const.SESSION_USER)).getId())) {
			if (r.getId() == id) {
				return new Result(false,"无法删除 自己的角色");

			}
		}
		if (id == 1)
			return new Result(false,"admin 无法删除");
		else {
				return new Result(this.deleteByIdAndPid(id) >= 0);
		}
	}

	/***
	 * 删除自己的同时 删除 所有 子节点 属性名 必需为pid
	 * 
	 * @param para
	 * @return
	 */
	public int deleteByIdAndPid(Integer id) {
		int result = this.deleteByPrimaryKey(id);

		List<SystemRole> list = this.selectByPid(id);

		for (SystemRole m : list) {
			deleteByIdAndPid(m.getId());
			this.deleteByPid(id);
		}

		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.caiyigo.zoo.service.RoleService#deleteByPid(java.lang.Integer)
	 */
	@Override
	public int deleteByPid(Integer id) {

		return roleMapper.deleteByPid(id);
	}

}
